<template>
    <el-card class="box-card">
        <div slot="header" class="clearfix">
            <span>菜单管理</span>
        </div>
        <el-alert title="Tips" style="margin-bottom: 20px;" type="warning"
            description="设置后台管理系统的左侧菜单，目前至多支持两层菜单，三层以上菜单将不会显示。" show-icon>
        </el-alert>
        <el-table stripe :expand-row-keys="['0']" :tree-props="{ children: 'children' }" :data="treeMenu"
            style="width: 100%;" row-key="permission_id" border>
            <el-table-column fixed label="资源名称" width="200">
                <template slot-scope="scope">
                    <span v-if="scope.row.resource_type_id === 2">{{ scope.row.menu_name }}</span>
                    <span v-if="scope.row.resource_type_id === 3">{{ scope.row.permission_remark }}</span>
                </template>
            </el-table-column>
            <el-table-column label="图标">
                <template slot-scope="scope">
                    <i :class="'el-icon-' + scope.row.icon_name"></i>
                </template>
            </el-table-column>
            <el-table-column label="资源类型">
                <template slot-scope="scope">
                    <el-tag :type="scope.row.resource_type_id === 3 ? 'warning' : ''">
                        {{ scope.row.resource_type_name }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="resource_type_code" label="资源代码" width="150"></el-table-column>
            <el-table-column prop="permission_code" label="权限代码" width="200"></el-table-column>
            <el-table-column prop="operation_name" label="操作名称"></el-table-column>
            <el-table-column prop="route_name" label="路由名称" width="150"></el-table-column>
            <el-table-column prop="route_full_path" label="完整路由地址" width="150"></el-table-column>
            <el-table-column prop="menu_order" label="菜单序号" width="150"></el-table-column>
            <el-table-column prop="permission_remark" label="备注"></el-table-column>
            <el-table-column fixed="right" label="操作" width="280">
                <template slot-scope="scope">
                    <el-button v-permission="'system:menu:edit'" icon="el-icon-edit" size="small" type="primary" plain
                        @click="openEdit(scope.row)"></el-button>
                    <el-button v-permission="'system:menu:create'" v-if="scope.row.resource_type_id !== 3"
                        icon="el-icon-circle-plus-outline" type="success" plain size="small"
                        @click="openInsert(scope.row)"></el-button>
                    <el-button v-permission="'system:menu:setting'" v-if="scope.row.resource_type_id !== 3"
                        icon="el-icon-setting" type="danger" plain size="small" @click="openIcon(scope.row)"></el-button>
                    <el-button v-permission="'system:menu:remove'" @click="handleRemove(scope.row)" icon="el-icon-delete"
                        type="danger" plain size="small"></el-button>
                </template>
            </el-table-column>
        </el-table>

        <!-- 添加 -->
        <el-dialog title="添加菜单/操作按钮" :visible.sync="insert_dialog_visible"
            @close="handleCloseDialog('insert_menu', 'insert_operate')">
            <el-tabs v-model="activeName" type="card">
                <el-tab-pane label="菜单" name="menu">
                    <el-form :model="insert_menu" ref="insert_menu" status-icon label-width="150px" :rules="rules">
                        <el-form-item label="菜单名称:" prop="menu_name">
                            <el-input type="text" v-model="insert_menu.menu_name" autocomplete="off"></el-input>
                        </el-form-item>
                        <el-form-item label="路由名称:" prop="route_id">
                            <el-cascader :options="route_list" v-model="insert_menu.route_id" ref="cascader"
                                :props="{ value: 'route_id', label: 'route_name', checkStrictly: true, emitPath: false }"
                                clearable placeholder="指定此菜单对应的路由" @change="handleChange"></el-cascader>
                        </el-form-item>
                        <el-form-item label="显示顺序:" prop="menu_order">
                            <el-input type="text" v-model="insert_menu.menu_order" autocomplete="off"
                                placeholder="显示顺序按照数字从小到大，如2001"></el-input>
                        </el-form-item>
                        <el-form-item label="权限代码:" prop="permission_code">
                            <el-input type="text" v-model="insert_menu.permission_code" autocomplete="off"
                                placeholder="权限代码由父级权限和菜单权限合成"></el-input>
                        </el-form-item>
                        <el-form-item label="权限备注:" prop="permission_remark">
                            <el-input type="text" v-model="insert_menu.permission_remark" autocomplete="off"
                                placeholder="菜单备注信息"></el-input>
                        </el-form-item>
                    </el-form>
                </el-tab-pane>
                <el-tab-pane label="操作按钮" name="operate_btn">
                    <el-form :model="insert_operate" ref="insert_operate" status-icon label-width="150px" :rules="rules">
                        <el-form-item label="操作类型:" prop="operation_name">
                            <el-select v-model="insert_operate.operation_name" @change="handleBtnChange"
                                placeholder="请选择操作按钮类型">
                                <el-option v-for="item in operation" :key="item.operation_id" :label="item.operation_name"
                                    :value="item.operation_code">
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="权限代码:" prop="permission_code">
                            <el-input type="text" v-model="insert_operate.permission_code" autocomplete="off"
                                name="permission_code" placeholder="权限代码由父级权限和按钮权限合成"></el-input>
                        </el-form-item>
                        <el-form-item label="权限备注:" prop="permission_remark">
                            <el-input type="text" v-model="insert_operate.permission_remark" autocomplete="off"
                                placeholder="请输入权限备注信息"></el-input>
                        </el-form-item>
                    </el-form>
                </el-tab-pane>
            </el-tabs>
            <span slot="footer" class="dialog-footer">
                <el-button @click="insert_dialog_visible = false">取 消</el-button>
                <el-button type="primary" @click="handleInsert">添加</el-button>
            </span>
        </el-dialog>

        <!-- 编辑 -->
        <el-dialog title="添加菜单/操作按钮" :visible.sync="edit_dialog_visible">
            <el-tabs v-model="activeName" type="card">
                <el-tab-pane label="菜单" name="menu" :disabled="this.edit_menu.resource_type_id === 3">
                    <el-form :model="edit_menu" ref="edit_menu" status-icon label-width="150px" :rules="rules">
                        <el-form-item label="菜单名称:" prop="name">
                            <el-input type="text" v-model="edit_menu.menu_name" autocomplete="off"></el-input>
                        </el-form-item>
                        <el-form-item label="路由名称:" prop="route_id">
                            <el-cascader :options="route_list" v-model="edit_menu.route_id"
                                :props="{ value: 'route_id', label: 'route_name', checkStrictly: true, emitPath: false }"
                                clearable placeholder="指定此菜单对应的路由"></el-cascader>
                        </el-form-item>
                        <el-form-item label="显示顺序:" prop="menu_order">
                            <el-input type="text" v-model="edit_menu.menu_order" autocomplete="off"
                                placeholder="显示顺序按照数字从小到大，如2001"></el-input>
                        </el-form-item>
                        <el-form-item label="权限代码:" prop="permission_code">
                            <el-input type="text" v-model="edit_menu.permission_code" autocomplete="off"
                                placeholder="权限代码由父级权限和菜单权限合成"></el-input>
                        </el-form-item>
                        <el-form-item label="权限备注:" prop="permission_remark">
                            <el-input type="text" v-model="edit_menu.permission_remark" autocomplete="off"
                                placeholder="菜单备注信息"></el-input>
                        </el-form-item>
                    </el-form>
                </el-tab-pane>
                <el-tab-pane label="操作按钮" name="operate_btn" :disabled="this.edit_operate.resource_type_id === 2">
                    <el-form :model="edit_operate" ref="edit_operate" status-icon label-width="150px" :rules="rules">
                        <el-form-item label="操作类型:" prop="operation_name">
                            <el-select v-model="edit_operate.operation_name" @change="handleBtn" placeholder="请选择操作按钮类型">
                                <el-option v-for="item in operation" :key="item.operation_id" :label="item.operation_name"
                                    :value="item.operation_code">
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="权限代码:" prop="permission_code">
                            <el-input type="text" v-model="edit_operate.permission_code" autocomplete="off"
                                placeholder="权限代码由父级权限和按钮权限合成"></el-input>
                        </el-form-item>
                        <el-form-item label="权限备注:" prop="permission_remark">
                            <el-input type="text" v-model="edit_operate.permission_remark" autocomplete="off"
                                placeholder="请输入权限备注信息"></el-input>
                        </el-form-item>
                    </el-form>
                </el-tab-pane>
            </el-tabs>
            <span slot="footer" class="dialog-footer">
                <el-button @click="edit_dialog_visible = false">取 消</el-button>
                <el-button type="primary" @click="handleEdit">保存</el-button>
            </span>
        </el-dialog>

        <!-- 图标 -->
        <el-dialog title="选择图标" :visible.sync="icon_dialog_visible" width="70%" @close="handleClose">
            <div class="icon_list">
                <div class="icon-box" v-for="icon in icons" :key="icon.icon_id" @click="handleIconColor(icon)"
                    :class="{ selected: isSelected(icon) }">
                    <i :class="'el-icon-' + icon.icon_name"></i>
                    <div>{{ icon.icon_name }}</div>
                </div>
            </div>
            <div class="page">
                <el-pagination background layout="prev, pager, next" :current-page="currentPage" :page-count="total_num"
                    @current-change="handleSwitch">
                </el-pagination>
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button @click="icon_dialog_visible = false">取 消</el-button>
                <el-button type="primary" @click="handleSelectIcon">确 定</el-button>
            </span>
        </el-dialog>
    </el-card>
</template>

<script>
import { mapActions, mapGetters, mapState, mapMutations } from 'vuex';

export default {
    name: "List",
    data() {
        return {
            insert_dialog_visible: false,
            insert_menu: {
                menu_name: '',
                route_id: '',
                menu_order: '',
                permission_code: '',
                permission_remark: '',
                resource_type_id: 2,
                resource_type_name: '菜单',
                resource_type_code: 'MENU',
            },
            insert_operate: {
                permission_code: '',
                permission_remark: '',
                operation_id: '',
                resource_type_code: '',
                resource_type_id: 3,
                resource_type_name: '操作',
                resource_type_code: 'OPERATION',
            },
            rules: {
                menu_order: [
                    { required: true, message: "请填写显示顺序", trigger: 'blur' },
                    {
                        pattern: /^\d+$/,
                        message: '显示顺序必须是数字！',
                        trigger: 'blur'
                    }
                ],
                menu_name: [{ required: true, message: "请输入菜单名称", trigger: 'blur' },],
                route_name: [{ required: true, message: "请选择路由名称", trigger: 'blur' },],
                permission_code: [{ required: true, message: "请输入权限代码", trigger: 'blur' },],
                permission_remark: [{ required: true, message: "请输入备注信息", trigger: 'blur' },],
            },
            activeName: "menu",
            options: [],
            edit_dialog_visible: false,
            edit_menu: {
                menu_name: '',
                route_id: '',
                menu_order: '',
                permission_code: '',
                permission_remark: '',
                resource_type_id: 2,
                resource_type_name: '菜单',
                resource_type_code: 'MENU',
            },
            edit_operate: {
                permission_code: '',
                permission_remark: '',
                operation_id: '',
                resource_type_code: '',
                resource_type_id: 3,
                resource_type_name: '操作',
                resource_type_code: 'OPERATION',
            },
            icon_dialog_visible: false,
            current_code: '',
            icon_menu: '',
            page_num: 30,
            total_num: 0,
            currentPage: 1,
        }
    },
    computed: {
        ...mapGetters('menu', ['treeMenu']),
        ...mapGetters('route', ['route_list']),
        ...mapState('operation', ['operation']),
        ...mapState('icon', ['icons']),
        ...mapState('icon', ['icons', 'selectIcon']),
        isSelected() {
            return (icon) => icon.icon_id === this.selectIcon;
        },
    },
    watch: {
        'edit_menu.resource_type_id'(newValue) {
            if (newValue === 3) {
                this.activeName = 'operate_btn';
            } else {
                this.activeName = 'menu';
            }
        },
        'insert_operate.operation_name'() {
            let operation_code = this.insert_operate.operation_code;
            this.insert_operate.permission_code = this.current_code + ':' + operation_code;
        },
        'edit_operate.operation_name'() {
            let operation_code = this.edit_operate.operation_code;
            let code = this.edit_operate.permission_code.split(":");
            this.edit_operate.permission_code = code[0] + ':' + operation_code;
        },
    },
    methods: {
        openInsert(menu) {
            this.insert_menu.permission_code = menu.permission_code;
            this.insert_menu.parent_id = menu.permission_id;
            this.insert_operate.permission_code = menu.permission_code;
            this.insert_operate.parent_id = menu.permission_id;
            this.current_code = this.insert_operate.permission_code;
            this.insert_dialog_visible = true;
        },
        openEdit(menu) {
            this.edit_menu = { ...menu };
            this.edit_operate = { ...menu };
            this.edit_dialog_visible = true;
        },
        ...mapActions('icon', ['icon_list']),
        async openIcon(icon) {
            let { status, msg, total } = await this.icon_list();
            if (status) {
                this.total_num = Math.ceil(total / this.page_num);
            }
            this.icon_menu = icon;
            this.icon_dialog_visible = true;
        },
        // 关闭弹窗，清除表单验证状态
        handleCloseDialog(formName1, formName2) {
            // formName是变量，不能使用 ref.formName
            this.$refs[formName1].resetFields();
            this.$refs[formName2].resetFields();
        },
        // 添加菜单或按钮
        ...mapActions('menu', ['add_menu']),
        ...mapActions('menu', ['add_operation']),
        handleInsert() {
            if (this.activeName === 'menu') {
                // 添加菜单
                this.$refs.insert_menu.validate(async (valid) => {
                    if (valid) {
                        let { status, msg } = await this.add_menu({ ...this.insert_menu });
                        if (status) {
                            this.$message.success(msg);
                            this.insert_dialog_visible = false;
                        } else {
                            this.$message.error(msg);
                        }
                    }
                });
            } else if (this.activeName === 'operate_btn') {
                // 添加操作按钮
                this.$refs.insert_operate.validate(async (valid) => {
                    if (valid) {
                        let { status, msg } = await this.add_operation({ ...this.insert_operate });
                        if (status) {
                            this.$message.success(msg);
                            this.insert_dialog_visible = false;
                        } else {
                            this.$message.error(msg);
                        }
                    }
                });
            }
        },
        // 编辑菜单或按钮
        ...mapActions('menu', ['update_menu']),
        ...mapActions('menu', ['update_operate']),
        handleEdit() {
            if (this.activeName === 'menu') {
                // 编辑菜单
                this.$refs.edit_menu.validate(async (valid) => {
                    if (valid) {
                        let { status, msg } = await this.update_menu({ ...this.edit_menu });
                        if (status) {
                            this.$message.success(msg);
                            this.edit_dialog_visible = false;
                        } else {
                            this.$message.error(msg);
                        }
                    }
                });
            } else if (this.activeName === 'operate_btn') {
                // 编辑操作按钮
                this.$refs.edit_operate.validate(async (valid) => {
                    if (valid) {
                        let { status, msg } = await this.update_operate({ ...this.edit_operate });
                        if (status) {
                            this.$message.success(msg);
                            this.edit_dialog_visible = false;
                        } else {
                            this.$message.error(msg);
                        }
                    }
                });
            }
        },
        // 删除菜单或操作按钮
        ...mapActions('menu', ['remove_menu']),
        ...mapActions('menu', ['remove_operation']),
        handleRemove(menu) {
            if (menu.resource_type_id === 2) {
                let { menu_id, permission_id } = menu;
                this.$confirm('该操作将永久删除该菜单, 是否继续?', '提示', { type: 'warning' })
                    .then(async () => {
                        let { status, msg } = await this.remove_menu({ menu_id, permission_id });
                        if (status) {
                            // 信息提示
                            this.$message.success(msg);
                        } else {
                            this.$message.error(msg);
                        }
                    }).catch(() => {
                        this.$message.info("已取消该操作！");
                    });
            } else if (menu.resource_type_id === 3) {
                let { permission_id } = menu;
                this.$confirm('该操作将永久删除该按钮, 是否继续?', '提示', { type: 'warning' })
                    .then(async () => {
                        let { status, msg } = await this.remove_operation({ permission_id });
                        if (status) {
                            // 信息提示
                            this.$message.success(msg);
                        } else {
                            this.$message.error(msg);
                        }
                    }).catch(() => {
                        this.$message.info("已取消该操作！");
                    });
            }
        },
        // 级联选择器
        handleChange() {
            let nodesInfo = this.$refs['cascader'].getCheckedNodes();
            this.insert_menu.route_name = nodesInfo[0].data.route_name;
            this.insert_menu.route_full_path = nodesInfo[0].data.route_full_path;
            this.insert_operate.operation_id = nodesInfo[0].data.operation_id;
        },
        // 获取operation_id
        handleBtnChange(btn) {
            let { operation_id, operation_name, operation_code } = this.operation.find(item => item.operation_code === btn);
            this.insert_operate.operation_id = operation_id;
            this.insert_operate.operation_name = operation_name;
            this.insert_operate.operation_code = operation_code;
        },
        handleBtn(btn) {
            let { operation_id, operation_name, operation_code } = this.operation.find(item => item.operation_code === btn);
            this.edit_operate.operation_id = operation_id;
            this.edit_operate.operation_name = operation_name;
            this.edit_operate.operation_code = operation_code;
        },
        // 图标颜色(再次点击颜色移除)
        ...mapActions('icon', ['select_icon']),
        handleIconColor(icon) {
            this.select_icon(icon);
        },
        // 设置图标
        ...mapActions('icon', ['upload_icon']),
        ...mapMutations('menu', ['UPDATE_ICON']),
        async handleSelectIcon() {
            let { status, msg, menu_icon } = await this.upload_icon({ icon_id: this.selectIcon, menu: this.icon_menu });
            if (status) {
                this.UPDATE_ICON({ icon: menu_icon, menu: this.icon_menu });
                this.$message.success(msg);
                this.icon_dialog_visible = false;
            } else {
                this.$message.error(msg);
            }
        },
        // 页码
        ...mapActions('icon', ['icon_list']),
        async handleSwitch(pageIndex) {
            this.currentPage = pageIndex;
            console.log(this.currentPage);
            await this.icon_list({ pageIndex });
        },
        handleClose() {
            this.currentPage = 1;
        }
    },
}

</script>

<style lang="less" scoped>
.icon_list {
    display: flex;
    flex-wrap: wrap;

    .icon-box {
        width: 100px;
        height: 100px;
        border: 1px solid #ccc;
        text-align: center;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;

        i {
            font-size: 30px;
        }

        &:hover {
            color: rgba(100, 100, 246, 0.645);
        }
    }

    .selected {
        background-color: rgba(100, 100, 246, 0.645);
        color: white;
        pointer-events: none;
    }

}

.page {
    display: flex;
    justify-content: flex-end;
    padding-top: 20px;
}
</style>
